﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

namespace iTool_Cetector
{
    public class FileChangeDetect
    {
        /// <summary>
        /// 定时器触发间隔
        /// </summary>
        private int TimeoutMillis { get; set; }
        private string Directory { get; set; }
        private string FilterType { get; set; }
        private Dictionary<string, EventValue> Events { get; set; }

        private readonly FileSystemWatcher watcher = new FileSystemWatcher();


        public FileChangeDetect(string filePath) : this(filePath, 1000)
        {

        }

        public FileChangeDetect(string filePath, int timeoutMillis)
        {
            this.TimeoutMillis = timeoutMillis;
            this.Directory = Path.GetDirectoryName(filePath);
            this.FilterType = $"*{Path.GetExtension(filePath)}";
            this.WatcherStart();
        }

        /// <summary>
        /// 初始化监听
        /// </summary>
        /// <param name="directory">需要监听的目录</param>
        /// <param name="filterType">需要监听的文件类型(筛选器字符串)</param>
        /// <param name="IsEnableRaising">是否启用监听</param>
        /// <param name="IsInclude">是否监听子目录</param>
        private void WatcherStart()
        {
            watcher.BeginInit();
            watcher.Filter = FilterType;
            watcher.IncludeSubdirectories = false;
            watcher.EnableRaisingEvents = true;
            //watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size;
            watcher.NotifyFilter = NotifyFilters.LastWrite;
            watcher.Path = this.Directory;

            watcher.Changed += (sender, e) => 
            {
                var fileName = Path.GetFileName(e.FullPath);

                if (this.Events.ContainsKey(fileName))
                {
                    Utils.Logger($"WatcherStart Changed {fileName}");
                    this.Events[fileName].Timer.Change(TimeoutMillis, Timeout.Infinite);
                }
            };

            watcher.EndInit();
        }

        public void StartWaitResult(Dictionary<string, Action<string>> keyValues)
        {
            this.Events = new Dictionary<string, EventValue>();
            foreach (var item in keyValues)
            {
                this.Events.Add(item.Key, new EventValue
                {
                    Action = item.Value,
                    Timer = new Timer(new TimerCallback(OnWatchedFileChange), item.Key, Timeout.Infinite, Timeout.Infinite)
                });
            }
        }

        private void OnWatchedFileChange(object state)
        {
            var key = state.ToString();
            var path = $"/var/iTool/{key}";
            if (File.Exists(path))
            {
                var content = File.ReadAllText(path);
                if (this.Events[key].OldValue != content)
                {
                    this.Events[key].OldValue = content;
                    this.Events[key].Action.Invoke(content);
                }
            }
        }
    }

    public class EventValue 
    {
        public string OldValue { get; set; }
        public Timer Timer { get; set; }
        public Action<string> Action { get; set; }
    }
}


